import "dart:math";
import "package:flutter/material.dart";
import "package:myapp/_common/global.dart";
import "../type.dart";
import "../../../_common/AsperctRaioImage.dart";
import "dart:ui" as ui;

// 动态图片展示
class DynamicImageListWidget extends StatelessWidget {
  final DynamicImageTextItem dynamicImageTextItem; //动态图片
  // 单图模式下，图片竖向则固定宽高，图片横向则宽度占满,高度按图片比例
  const DynamicImageListWidget({
    super.key,
    required this.dynamicImageTextItem,
  });
  @override
  Widget build(BuildContext context) {
    ScreenUnit.init(context);
    List<String> dynamicImageList = dynamicImageTextItem.imageList;
    String dynamicImageListType = dynamicImageTextItem.dynamicImageListType;
    return Container(
      margin: const EdgeInsets.only(bottom: 8),
      child: dynamicImageList.isEmpty
          ? const SizedBox()
          : dynamicImageList.length == 1
              ? Padding(
                  padding: const EdgeInsets.only(left: 12, right: 12),
                  child: ClipRRect(
                    borderRadius: BorderRadius.circular(4),
                    child: Row(
                      children: [
                        AsperctRaioImage.asset(dynamicImageList[0],
                            builder: (context, snapshot, url) {
                          ui.Image data = snapshot.data as ui.Image;
                          if (data.width >= data.height) {
                            // 横图
                            return Expanded(
                              flex: 1,
                              child: Image.asset(
                                url,
                                fit: BoxFit.cover,
                              ),
                            );
                          } else {
                            // 竖图
                            return SizedBox(
                              width: 240,
                              height: 320,
                              child: Image.asset(
                                url,
                                fit: BoxFit.cover,
                              ),
                            );
                          }
                        }),
                      ],
                    ),
                  ),
                )
              : dynamicImageListType == 'card'
                  ? ImageCardList(
                      dynamicImageTextItem: dynamicImageTextItem,
                      dynamicImageListType: dynamicImageListType,
                    )
                  : ImageRowList(
                      dynamicImageTextItem: dynamicImageTextItem,
                      dynamicImageListType: dynamicImageListType,
                    ),
    );
  }
}

class ImageCardList extends StatelessWidget {
  final DynamicImageTextItem dynamicImageTextItem; //动态图片
  final String dynamicImageListType; //动态图片（多图）展示方式 card九宫格，row大图行滚动
  // 单图模式下，图片竖向则固定宽高，图片横向则宽度占满,高度按图片比例
  const ImageCardList({
    super.key,
    required this.dynamicImageTextItem,
    required this.dynamicImageListType,
  });
  // 2张图 [] []
  // 3张图 [] [] []
  // 4张图 [] [] [?]
  //       [] []
  // 5-9
  //       [] [] []
  //       [] [5] [6]
  //       [7] [8] [9]
  @override
  Widget build(BuildContext context) {
    List<String> dynamicImageList = dynamicImageTextItem.imageList;
    List<List<String>> list = [];
    if (dynamicImageList.length != 4) {
      int start = 0;
      int end = min(3, dynamicImageList.length);
      while (start < dynamicImageList.length) {
        list.add(dynamicImageList.sublist(start, end));
        start += 3;
        end = min(end + 3, dynamicImageList.length);
      }
      // 对不满三个的行补充到三行
      for (int i = 0; i < list.length; i++) {
        if (list[i].length != 3) {
          list[i].addAll(
            List.generate(
              3 - list[i].length,
              (index) => '',
            ),
          );
        }
      }
      // 每三个进行分割
    } else {
      list.add(dynamicImageList.sublist(0, 2));
      list[0].add('');
      list.add(dynamicImageList.sublist(2, 4));
      list[1].add('');
    }
    return Padding(
      padding: const EdgeInsets.only(left: 12, right: 6),
      child: Column(
        children: list.map((row) {
          List<Widget> arr = [];
          for (int i = 0; i < row.length; i++) {
            var e = row[i];
            arr.add(Expanded(
              flex: 1,
              child: Container(
                margin: const EdgeInsets.only(right: 6, bottom: 6),
                child: ClipRRect(
                  borderRadius: BorderRadius.circular(4),
                  child: e == ''
                      ? SizedBox(
                          width: ScreenUnit.setSp(96),
                        )
                      : AspectRatio(
                          aspectRatio: 1,
                          child: Image.asset(
                            e,
                            fit: BoxFit.cover,
                            width: ScreenUnit.setSp(96),
                          ),
                        ),
                ),
              ),
            ));
          }
          return Row(children: arr);
        }).toList(),
      ),
    );
  }
}

class ImageRowList extends StatelessWidget {
// 图片宽度固定，外边距固定，
// 当单个图片宽度超过容器宽度，则滑动时图片在容器中心，图片两侧与边距会在屏幕之外
// 当单个图片宽度小于容器宽度，则滑动时如果图片左侧能到达容器左侧，则左对齐，否则右侧与容器右侧对齐
  final DynamicImageTextItem dynamicImageTextItem; //动态图片
  final String dynamicImageListType; //动态图片（多图）展示方式 card九宫格，row大图行滚动
  // 单图模式下，图片竖向则固定宽高，图片横向则宽度占满,高度按图片比例
  const ImageRowList({
    super.key,
    required this.dynamicImageTextItem,
    required this.dynamicImageListType,
  });
  // 每个元素的宽度
  final double itemWidth = 320;
  final double startPadding = 12;
  final double endPadding = 12;
  final double intervalPadding = 6;
  final double ratio = 1.1; //高：宽
  @override
  Widget build(BuildContext context) {
    final double itemHeight = itemWidth * ratio; //子元素高度
    List<String> dynamicImageList = dynamicImageTextItem.imageList;
    return SizedBox(
      height: itemHeight,
      width: double.infinity,
      child: ListView.builder(
          physics: ImageRowListScrollPhysics(
            itemWidth: itemWidth,
            startPadding: startPadding,
            endPadding: endPadding,
            intervalPadding: intervalPadding,
          ),
          scrollDirection: Axis.horizontal,
          itemCount: dynamicImageList.length,
          itemBuilder: (BuildContext context, int index) {
            late EdgeInsets margin;

            if (index == 0) {
              margin =
                  EdgeInsets.only(left: startPadding, right: intervalPadding);
            } else if (index == dynamicImageList.length - 1) {
              margin = EdgeInsets.only(right: endPadding);
            } else {
              margin = EdgeInsets.only(right: intervalPadding);
            }
            return Container(
              margin: margin,
              child: ClipRRect(
                borderRadius: BorderRadius.circular(4),
                child: SizedBox(
                  width: itemWidth,
                  height: itemHeight,
                  child: Image.asset(
                    dynamicImageList[index],
                    fit: BoxFit.cover,
                  ),
                ),
              ),
            );
          }),
    );
  }
}

class ImageRowListScrollPhysics extends PageScrollPhysics {
  final double startPadding;
  final double endPadding;
  final double intervalPadding;
  final double itemWidth; //单元宽度或高度
  const ImageRowListScrollPhysics({
    super.parent,
    required this.startPadding,
    required this.endPadding,
    required this.intervalPadding,
    required this.itemWidth,
  });

  // 实现覆盖
  @override
  ImageRowListScrollPhysics applyTo(ScrollPhysics? ancestor) {
    return ImageRowListScrollPhysics(
      parent: buildParent(ancestor),
      startPadding: startPadding,
      endPadding: endPadding,
      intervalPadding: intervalPadding,
      itemWidth: itemWidth,
    );
  }

  // 每页的目标距离是图片的中心到滚动开始的距离
  // 首尾单元如果由于滚动视图宽度大于单元宽度，则视为到达滚动边缘
  double _getPixels(ScrollMetrics position, double page) {
    // print('[page]:$page');
    // 间隔距离
    double intervalWidth = page * intervalPadding;
    double res = page * itemWidth +
        startPadding +
        intervalWidth +
        (itemWidth - position.viewportDimension) / 2;
    return res;
    // return page * position.viewportDimension;
  }

  double _getPage(ScrollMetrics position) {
    // 如果单元宽度小于滚动视图容器宽度，则使用单元宽度
    if (itemWidth < position.viewportDimension) {
      return position.pixels / itemWidth;
    }
    return position.pixels / position.viewportDimension;
  }

  double _getTargetPixels(
      ScrollMetrics position, Tolerance tolerance, double velocity) {
    double page = _getPage(position);
    // print('[page]:$page');
    // print('[_getTargetPixels]:$velocity | ${tolerance.velocity}');
    // 如果当前向左滑动速度超出阈值，则判断为向上一页滑动
    if (velocity < -tolerance.velocity) {
      page -= 0.5;
    }
    // 如果当前向右滑动速度超出阈值，则判断为向下一页滑动
    else if (velocity > tolerance.velocity) {
      page += 0.5;
    }
    // +-0.5为了四舍五入保证目标页数正确
    return _getPixels(position, page.roundToDouble());
  }

  @override
  double applyBoundaryConditions(
    ScrollMetrics position,
    double value,
  ) {
    // 自定义边界条件
    return super.applyBoundaryConditions(position, value);
  }

  @override
  Simulation? createBallisticSimulation(
    ScrollMetrics position,
    double velocity,
  ) {
    // print("[itemWidth]:$itemWidth"); //单元宽度
    // print("[position.pixels]:${position.pixels}"); //距离滚动开始边缘的偏移
    // print(
    //     "[position.viewportDimension]:${position.viewportDimension}"); //当前滚动方向上视口尺寸
    // print("[position.minScrollExtent]:${position.minScrollExtent}"); //最小滚动
    // print("[position.maxScrollExtent]:${position.maxScrollExtent}"); //最大滚动
    // print("[velocity]:$velocity"); //滑动速度
    // 自定义模拟动画
    // 如果速度小于0（向开始方向滑动），并且到达开始边界
    // 或者速度大于0（向结束方向滑动），并且到达结束边界
    if ((velocity <= 0.0 && position.pixels <= position.minScrollExtent) ||
        (velocity >= 0.0 && position.pixels >= position.maxScrollExtent)) {
      // 调用原来的效果（边缘拖拽）
      return super.createBallisticSimulation(position, velocity);
    }
    final Tolerance tolerance = toleranceFor(position); //滑动动画

    double target = _getTargetPixels(position, tolerance, velocity); //滑动目标
    // print('[target]:$target');
    // // 如果目标位置 不是当前位置？则使用弹性动画到达目标位置
    if (target != position.pixels) {
      return ScrollSpringSimulation(spring, position.pixels, target, velocity,
          tolerance: tolerance);
    }
    // 否则停止滚动
    return null;
  }

  @override
  bool get allowImplicitScrolling => false;
}
